﻿package bakudo.engines.mapEngine.controller.renderer 
{
	import bakudo.engines.mapEngine.BakudoMapEngine;
	import bakudo.engines.mapEngine.model.actors.ModelActor;
	import bakudo.engines.mapEngine.model.grid.GridCell;
	import bakudo.engines.mapEngine.model.WorldModel;
	import bakudo.utils.misc.TwoDimmPosition;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	/**
	 * ...
	 * @author Bakudo
	 */
	public class ViewRenderer
	{

		
		public var core : BakudoMapEngine;
		

		
		public function ViewRenderer(core:BakudoMapEngine) 
		{
			this.core = core;
		}
	
		
		
	//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	// PUBLIC METHODS
	//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	
		public function doRenderView():void {
			var m : WorldModel = core.worldModel;
			var camPos : Point = m.cameraPosition;
			var tmpPos : Point = new Point();
			var tLCorner : Point = new Point();
			var arrayPos : TwoDimmPosition;
			var offset : Point = new Point();
			var center : Point = new Point(m.viewWidth * .5, m.viewHeight * .5);
			var floorBd : BitmapData = core.scene2D.floorLayer.bitmapData;
			var i : uint;
			var inRowCount : uint = m.gridViewDistance * 2 + 1;
			var n : uint = Math.pow(inRowCount,2);
			var rIndex : uint;
			var cIndex : uint;
			var actor : ModelActor;
			var cell : GridCell;
			floorBd.fillRect(new Rectangle(0, 0, m.viewWidth, m.viewHeight),0x00FF0000);
			
			tLCorner.x = camPos.x - m.viewWidth * .5; 
			tLCorner.y = camPos.y - m.viewHeight * .5; 
			tmpPos = tLCorner.clone();
			
			var arr : Array = [];
			var pt : Point; 
			var actorBd : BitmapData;
			var actorViewRect : Rectangle;
			var bitmapAreaRect : Rectangle;
						
			
			//	rectangle in camera space coordintations
			var viewRect : Rectangle = new Rectangle;
			viewRect.x = camPos.x - m.viewWidth * .5;
			viewRect.y = camPos.y - m.viewHeight * .5;
			viewRect.width = m.viewWidth;
			viewRect.height = m.viewHeight;
			
			while (i < n) {
				arrayPos = getTwoDimmUnderPoint(tmpPos);
				if (arrayPos.bothPositive) {
					cell = m.mapGrid[arrayPos.r][arrayPos.c];
					actor = cell.backgroundTile;
					if (actor) {
						pt = new Point();
						actorViewRect = getInterSectionArea(actor, viewRect);
						
						// obszar bitmapy widoku ktory wycinamy
						bitmapAreaRect = actorViewRect.clone();
						bitmapAreaRect.x = actorViewRect.x - actor.position.x;
						bitmapAreaRect.y = actorViewRect.y - actor.position.y;
						
						// offset wzgledem widoku
						offset.x = (camPos.x - actor.position.x - bitmapAreaRect.x);
						offset.y = (camPos.y - actor.position.y - bitmapAreaRect.y);
						
						// pozycja w ktorej rysujemy
						pt.x = center.x - offset.x;
						pt.y = center.y - offset.y;
						
						
						floorBd.copyPixels(m.getViewByClassName(actor.viewClassName),bitmapAreaRect,pt);
					}
					for (var io in cell.members) {
						
					}
				}
				if (cIndex < inRowCount-1) {
					tmpPos.x += m.gridSize;
					cIndex++;
				}else {
					tmpPos.x = tLCorner.clone().x;
					tmpPos.y += m.gridSize;
					cIndex = 0;
					rIndex ++;
				}
				i++;
				actor = null;
			}
		}
		
		
		
	//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	// PRIVATE METHODS
	//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function renderObstacles(arr:Array):void {
			
		}
	
		private function getInterSectionArea(actor:ModelActor,viewRect:Rectangle):Rectangle{
				// obszar widoku wzgledem przestrzeni modelu
			var actorBound : Rectangle = core.worldModel.getActorViewBoundary(actor);
			return viewRect.intersection(actorBound);
		}
		
		/**
		 * Zwraca index (r,c) pola mapy w tablicy na podstawie pozycji
		 * @param	TwoDimmPosition - pozycja
		 * @return index tablicy dwuwymiarowej w formacie (row,column)
		 */
		private function getTwoDimmUnderPoint(point:Point):TwoDimmPosition {
			var p : TwoDimmPosition = new TwoDimmPosition();
			var gridSize : uint = core.worldModel.gridSize;
			p.r = Math.floor(point.y / gridSize);
			p.c = Math.floor(point.x / gridSize);
			return p;
		}
	}

}